package de.gwtprime.server.servlets;

import org.apache.commons.lang3.StringUtils;

import de.gwtprime.client.util.AppUtils;
import de.gwtprime.server.model.Answer;
import de.gwtprime.server.model.Article;
import de.gwtprime.server.model.ArticleSection;
import de.gwtprime.server.model.Question;
import de.gwtprime.shared.util.AppUtilsShared;

public class CrawlServletHelper {

	public enum CRAWLABLE_ENTITIES{
		
		ROOT(null),
		ARTICLE(Article.class),
		ARTICLE_SECTION(ArticleSection.class),
		Question(Question.class);
		
		private Class<?> entityClass;
		
		CRAWLABLE_ENTITIES(Class<?> entityClass){
			this.entityClass = entityClass;
		}
		
		public String getClassName(){
			if(getEntityClass()==null){
				return "";
			}else{
				return getEntityClass().getSimpleName();
			}
		}

		public Class<?> getEntityClass() {
			return entityClass;
		}
	}
	
	public static String contentSeparator = "<br/>";
	
	/**
	 * Get Entity name from URL
	 * E.g.: "http://gwt-prime.appspot.com/#!Article:1" -> "Article"
	 * @param url Complete URL
	 * @return Entity name between "#!" and ":"
	 */
	public static String getEntityUrl(String url) {
		
		int firstIndex = url.indexOf(AppUtilsShared.hashFragmentEscaped);
		int lastIndex = url.lastIndexOf(":");
		
		if(firstIndex < 0 || lastIndex <0 || lastIndex < firstIndex){
			return "";
		}
		
		return url.substring(firstIndex+AppUtilsShared.hashFragmentEscaped.length(), lastIndex);
		
	}
	
	/**
	 * Get the entity from the url
	 * E.g.: "http://gwt-prime.appspot.com/#!Article:1" -> "1"
	 * @param url
	 * @return
	 */
	public static Long getIdFromUrl(String url){
		int lastIndex = url.lastIndexOf(":");
		
		if(lastIndex<0)
			return null;
		
		try{
			return Long.parseLong(url.substring(lastIndex+1, url.length()));
		}catch(Exception e){
			return null;
		}
	}
	
	/**
	 * Get the content for the welcome page and serve it to the google crawler
	 * @return
	 */
	public static String getWelcomePageContentForGoogle(){
		
		String result = "";
		for(Article article : Article.loadLatestArticles(10)){
			result += replace(article.getText())+contentSeparator;
			result += replace(article.getTitle())+contentSeparator;
			result += String.format("<a href=\"%s\">%s</a>", 
					AppUtilsShared.generateGWTUrl(CRAWLABLE_ENTITIES.ARTICLE.getClassName(), article.getId()),
							article.getTitle()
							) +contentSeparator;
		}
		
		return result;
	}
	
	/**
	 * Get the article content (and article sections) for the given id for the google crawler
	 * @param id
	 * @return
	 */
	public static String getArticleContentForGoogle(Long id){
		
		String result = "";
		
		Article article = Article.findArticle(id);
		result += replace(article.getText())+contentSeparator;
		result += replace(article.getTitle())+contentSeparator;
		
		for(ArticleSection section : article.getSections()){
			result += replace(section.getTitle()) +contentSeparator;
			result += replace(section.getText()) +contentSeparator;
			
			// print images
			result += "images: ";
			for(String imgUrl : AppUtils.getImageUrls(section.getImages())){
				result += String.format("<img src='%s' alt='%s'/>", imgUrl, section.getTitle()+ " image");
			}
			
		}
		
		return result;
	}
	
	/**
	 * Get the article section content for the given id for the google crawler
	 * @param id
	 * @return
	 */
	public static String getArticleSectionContentForGoogle(Long id){
		
		String result = "";
		
		ArticleSection articleSection = ArticleSection.findArticleSection(id);
		result += replace(articleSection.getText())+contentSeparator;
		result += replace(articleSection.getTitle())+contentSeparator;
		
		return result;
	}
	
	/**
	 * Get the question content for the given id for the google crawler
	 * @param id
	 * @return
	 */
	public static String getQuestionContentForGoogle(Long id){
		
		String result = "";
		
		Question question = Question.findQuestion(id);
		result += replace(question.getText())+contentSeparator;
		result += replace(question.getTitle())+contentSeparator;
		
		for(Answer answer : question.getAnswers()){
			result += replace(answer.getText()) +contentSeparator;
		}
		
		return result;
	}
	
	/**
	 * Replace e.g. code tags
	 * @param text
	 * @return
	 */
	public static String replace(String text){
		
		return StringUtils.replaceEach(text,
		        new String[]{"&", "<", ">", "\"", "'", "/"},
		        new String[]{"&amp;", "&lt;", "&gt;", "&quot;", "&#x27;", "&#x2F;"});
		
	}
	
}
